//////////////////////////////////////////////
// ProgramSourcesHolder.h
//
//////////////////////////////////////////////

/// Defines / Macros -------------------------

#pragma once

/// Includes ---------------------------------

// nkGraphics
#include "../Dll/DllDefines.h"

// nkMemory
#include <NilkinsMemory/Containers/BufferCast.h>
#include <NilkinsMemory/Containers/String.h>
#include <NilkinsMemory/Containers/StringView.h>

/// Internals --------------------------------

namespace nkGraphics
{
	struct DLL_GRAPHICS_EXPORT MacroEntry
	{
		nkMemory::String _key ;
		nkMemory::String _value ;
	} ;
}

/// Class ------------------------------------

namespace nkGraphics
{
	class DLL_GRAPHICS_EXPORT ProgramSourcesHolder final
	{
		public :

			// Getters
			nkMemory::StringView getVertexMemory () const ;
			nkMemory::StringView getHullMemory () const ;
			nkMemory::StringView getDomainMemory () const ;
			nkMemory::StringView getGeometryMemory () const ;
			nkMemory::StringView getPixelMemory () const ;
			nkMemory::StringView getComputeMemory () const ;
			nkMemory::StringView getRaytracingMemory () const ;
			const nkMemory::BufferCast<MacroEntry>& getDefineMacrosVertex () const ;
			const nkMemory::BufferCast<MacroEntry>& getDefineMacrosHull () const ;
			const nkMemory::BufferCast<MacroEntry>& getDefineMacrosDomain () const ;
			const nkMemory::BufferCast<MacroEntry>& getDefineMacrosGeometry () const ;
			const nkMemory::BufferCast<MacroEntry>& getDefineMacrosPixel () const ;
			const nkMemory::BufferCast<MacroEntry>& getDefineMacrosCompute () const ;
			const nkMemory::BufferCast<MacroEntry>& getDefineMacrosRaytracing () const ;
			unsigned int getDefineMacroMaxNumber () const ;
			unsigned int getDefineMacroMaxNumberPipeline () const ;
			unsigned int getDefineMacroNumberCompute () const ;
			unsigned int getDefineMacroNumberRaytracing () const ;

			// Setters
			void setVertexMemory (nkMemory::StringView str) ;
			void setHullMemory (nkMemory::StringView str) ;
			void setDomainMemory (nkMemory::StringView str) ;
			void setGeometryMemory (nkMemory::StringView str) ;
			void setPixelMemory (nkMemory::StringView str) ;
			void setComputeMemory (nkMemory::StringView str) ;
			void setRaytracingMemory (nkMemory::StringView str) ;
			void addDefineMacroVertex (nkMemory::StringView key, nkMemory::StringView value) ;
			void addDefineMacroHull (nkMemory::StringView key, nkMemory::StringView value) ;
			void addDefineMacroDomain (nkMemory::StringView key, nkMemory::StringView value) ;
			void addDefineMacroGeometry (nkMemory::StringView key, nkMemory::StringView value) ;
			void addDefineMacroPixel (nkMemory::StringView key, nkMemory::StringView value) ;
			void addDefineMacroCompute (nkMemory::StringView key, nkMemory::StringView value) ;
			void addDefineMacroRaytracing (nkMemory::StringView key, nkMemory::StringView value) ;

			// Utilitaires
			bool hasMinimalDefinitionsPipeline () const ;
			bool hasMinimalDefinitionsCompute () const ;
			bool hasMinimalDefinitionsGeometry () const ;
			bool hasMinimalDefinitionsRaytracing () const ;
			void copyDefinesFrom (const ProgramSourcesHolder& other) ;

		private :

			// Attributes
			nkMemory::String _vertexMemory ;
			nkMemory::String _hullMemory ;
			nkMemory::String _domainMemory ;
			nkMemory::String _geometryMemory ;
			nkMemory::String _pixelMemory ;
			nkMemory::String _computeMemory ;
			nkMemory::String _raytracingMemory ;

			nkMemory::BufferCast<MacroEntry> _macrosVertex ;
			nkMemory::BufferCast<MacroEntry> _macrosHull ;
			nkMemory::BufferCast<MacroEntry> _macrosDomain ;
			nkMemory::BufferCast<MacroEntry> _macrosGeometry ;
			nkMemory::BufferCast<MacroEntry> _macrosPixel ;
			nkMemory::BufferCast<MacroEntry> _macrosCompute ;
			nkMemory::BufferCast<MacroEntry> _macrosRaytracing ;
	} ;
}